#include "StdAfx.h"
#include "DrumInstrument.h"
#include "Notes.h"


CDrumInstrument::CDrumInstrument(void)
{
}


CDrumInstrument::~CDrumInstrument(void)
{
}

void CDrumInstrument::Start( void )
{
	mDrumNoise.SetSampleRate( GetSampleRate() );
	mDrumNoise.SetBeatsPerMinute( GetBPM() );
	mDrumNoise.Start();
	mTime = 0;


	mAmpADSR.SetSource( &mDrumNoise );
	mAmpADSR.SetSampleRate( GetSampleRate() );
	mAmpADSR.SetBeatsPerMinute( GetBPM() );
	mAmpADSR.SetSustainVolume(0.2);
	mAmpADSR.Start();

}

bool CDrumInstrument::Generate( void )
{
	mDrumNoise.Generate();

	SetFreq(mFreq/2);
	
	bool lValid = mAmpADSR.Generate();

	mFrame[0] = mAmpADSR.Frame(0);
	mFrame[1] = mAmpADSR.Frame(1);

	mTime += GetSamplePeriod();

	return lValid;
}

void CDrumInstrument::SetNote( CNote *aNote )
{
	// Get a list of all attribute nodes and the
    // length of that list
    CComPtr<IXMLDOMNamedNodeMap> attributes;
    aNote->Node()->get_attributes(&attributes);
    long len;
    attributes->get_length(&len);

    // Loop over the list of attributes
    for(int i=0;  i<len;  i++)
    {
        // Get attribute i
        CComPtr<IXMLDOMNode> attrib;
        attributes->get_item(i, &attrib);

        // Get the name of the attribute
        CComBSTR name;
        attrib->get_nodeName(&name);

        // Get the value of the attribute.  A CComVariant is a variable
        // that can have any type. It loads the attribute value as a
        // string (UNICODE), but we can then change it to an integer 
        // (VT_I4) or double (VT_R8) using the ChangeType function 
        // and then read its integer or double value from a member variable.
        CComVariant value;
        attrib->get_nodeValue(&value);

        if(name == "duration")
        {
			value.ChangeType(VT_R8);
			SetDuration(value.dblVal);
        }
		else if(name == "note")
		{
			SetFreq(NoteToFrequency(value.bstrVal));
        }

	}
}